package org.example.notificationservice.service;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.notificationservice.entity.Notification;
import org.example.notificationservice.entity.NotificationTemplate;
import org.example.notificationservice.repository.NotificationRepository;
import org.example.notificationservice.repository.NotificationTemplateRepository;
import org.example.notificationservice.sender.NotificationSender;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class NotificationService {
    private final NotificationRepository notificationRepository;
    private final NotificationTemplateRepository templateRepository;
    private final List<NotificationSender> notificationSenders;

    public Notification createNotification(String userId, String templateId, Map<String, Object> params) {
        NotificationTemplate template = templateRepository.findById(templateId)
                .orElseThrow(() -> new RuntimeException("Template not found"));

        Notification notification = new Notification();
        notification.setUserId(userId);
        notification.setTitle(template.getSubject());
        notification.setContent(template.getContent());
        notification.setType(template.getType());
        notification.setStatus(Notification.NotificationStatus.PENDING);
        notification.setPriority(Notification.NotificationPriority.MEDIUM);
        notification.setMetadata(params);
        notification.setCreatedAt(LocalDateTime.now());

        return notificationRepository.save(notification);
    }

    public void sendNotification(Notification notification) {
        NotificationSender sender = notificationSenders.stream()
                .filter(s -> s.supports(notification.getType()))
                .findFirst()
                .orElseThrow(() -> new RuntimeException("No sender found for notification type: " + notification.getType()));

        try {
            sender.send(notification);
            notification.setStatus(Notification.NotificationStatus.SENT);
            notification.setSentAt(LocalDateTime.now());
        } catch (Exception e) {
            notification.setStatus(Notification.NotificationStatus.FAILED);
            log.error("Failed to send notification", e);
        }

        notificationRepository.save(notification);
    }

    public void scheduleNotification(Notification notification, LocalDateTime scheduledTime) {
        notification.setStatus(Notification.NotificationStatus.SCHEDULED);
        notification.setScheduledAt(scheduledTime);
        notificationRepository.save(notification);
    }

    public List<Notification> getPendingNotifications() {
        return notificationRepository.findByStatus(Notification.NotificationStatus.PENDING);
    }

    public List<Notification> getScheduledNotifications() {
        return notificationRepository.findByStatusAndScheduledAtBefore(
                Notification.NotificationStatus.SCHEDULED,
                LocalDateTime.now()
        );
    }
}